package com.ruoyi.project.system.service.impl;

import com.ruoyi.project.system.domain.DoctorRota;
import com.ruoyi.project.system.mapper.DoctorRotaMapper;
import com.ruoyi.project.system.service.IDoctorRotaService;
import com.ruoyi.project.system.domain.vo.RotaDateVO;
import com.ruoyi.project.system.domain.vo.RotaPeriodVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 医生排班服务实现
 */
@Service
public class DoctorRotaServiceImpl implements IDoctorRotaService {

    @Autowired
    private DoctorRotaMapper doctorRotaMapper;

    // 日期格式化（统一为 yyyy-MM-dd）
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    private static final Logger log = LoggerFactory.getLogger(IDoctorRotaService.class);
    @Override
public List<RotaDateVO> get7DaysRota(String doctorId) {
    try {
        // 1. 日期范围计算（保持不变）
        Date now = new Date();
        //这一步可以动态调整出勤周期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        Calendar startCal = Calendar.getInstance();
        startCal.setTime(now);
        startCal.add(Calendar.DATE, 0); // 不往前推，从当天开始
        String startDate = sdf.format(startCal.getTime());

        Calendar endCal = Calendar.getInstance();
        endCal.setTime(now);
        endCal.add(Calendar.DATE, 6); // 往后推6天
        String endDate = sdf.format(endCal.getTime());

        // 2. 查询数据库（已通过SQL过滤 currentDate_ = null）
        List<DoctorRota> rotaList = doctorRotaMapper.select7DaysRota(doctorId, startDate, endDate);

        if (CollectionUtils.isEmpty(rotaList)) {
            log.info("医生ID={} 近7天无有效排班记录", doctorId);
            return new ArrayList<>();
        }

        // 核心修复2：双重防护，过滤 currentDate_ 为 null 的记录（避免SQL过滤失效）
        List<DoctorRota> validRotaList = rotaList.stream()
                .filter(rota -> rota.getCurrentDate() != null) // 过滤 null 日期
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(validRotaList)) {
            log.warn("医生ID={} 近7天排班记录均为无效（currentDate_ 为 null）", doctorId);
            return new ArrayList<>();
        }

        // 3. 按日期分组（此时已无 null 日期，可安全格式化）
        Map<String, List<DoctorRota>> dateGroupMap = validRotaList.stream()
                .collect(Collectors.groupingBy(rota -> sdf.format(rota.getCurrentDate())));

        // 4. 转换VO并排序（保持不变）
        List<RotaDateVO> result = new ArrayList<>();
        for (String dateStr : dateGroupMap.keySet()) {
            RotaDateVO vo = new RotaDateVO();
            vo.setDate(dateStr);
            vo.setAvailable(true);
            result.add(vo);
        }

        result.sort(Comparator.comparing(RotaDateVO::getDate));
        return result;

    } catch (Exception e) {
        log.error("查询医生ID={} 近7天排班失败", doctorId, e);
        return new ArrayList<>();
    }
}

    @Override
    public RotaPeriodVO getRotaPeriod(String doctorId, String date) {
        RotaPeriodVO periodVO = new RotaPeriodVO();
        // 默认都不可约
        periodVO.setMorning(false);
        periodVO.setAfternoon(false);

        // 1. 查询当天排班记录
        List<DoctorRota> rotaList = doctorRotaMapper.selectRotaByDoctorAndDate(doctorId, date);
        if (CollectionUtils.isEmpty(rotaList)) {
            return periodVO;
        }

        // 2. 根据timeId判断时段（奇数=上午，偶数=下午）
        for (DoctorRota rota : rotaList) {
            Integer timeId = rota.getTimeId();
            if (timeId == null) {
                continue;
            }
            if (timeId % 2 == 1) {
                // 奇数=上午，标记为可约
                periodVO.setMorning(true);
            } else {
                // 偶数=下午，标记为可约
                periodVO.setAfternoon(true);
            }
        }

        return periodVO;
    }
}